# coding: utf-8
'''
Created on 21/06/2013

@author: Vagner Clementino
'''

import random
import pollard_rho
import get_generator
from sys import argv
from primeGen import random_int_gen
from primeGen import miller_rabin
import time

if __name__ == '__main__':
    
    
    '''
        Sintaxe do programa:
        main -d [numero de dígitos do primo] -e [numero de execuções] -t [parametro de seguranca]
    '''
    if len (argv) == 7:
        #sintexa correta
        
        log = open("discrete_log.log","a+" )
        log.write('''**********************************************************\n''')
           
        num_digits = int(argv[2])
        num_execs = int (argv[4]) #Numero de execuções do algoritmo
        log.write("Detalhes da execução:\n")
        log.write("[{}]\n".format(time.asctime(time.localtime(time.time()))))
        log.write ("Numero de digitos: {}\n".format(num_digits))
        log.write("Numero de execuções: {}\n".format(num_execs))
        log.write('''************************\n\n''')
        
        '''
        O parametro de segurança define o grau de confiança que o 
        inteiro gerado é primo. É provado que a probilidade de um numero
        testado não ser primo quando o algoritmo afirma que ele é primo é igual 
        a 1 / 4 ^ t, onde t é o parametro de segurança
        '''
        seg_param = int (argv[6]) 
        
        for i in xrange (0, num_execs):
            #Executa o loop ate encontrar um primo 
            while True:
                inteiro_gerado = random_int_gen.int_gerenator(num_digits)
                #Verificando se o número gerado é primo
                eh_primo = miller_rabin.miller_rabin_prime_teste(inteiro_gerado,seg_param)
                if eh_primo:
                    start_time = time.time()
                    prime = inteiro_gerado
                    #Encontrando o gerador para o grupo
                    alpha =  get_generator.get_generator(prime)
                    #Escolhendo aleatoriamente um elemento do grupo
                    beta = random.randint(1,(prime-1))  
        
                    discrete_log = pollard_rho.pollard_rho(prime, alpha, beta)
                    # Caso seja possível calcular o logaritmos dicreto
                    # o mesmo será exibido, do contrarío um novo valor
                    # sera tentado
                    if discrete_log != None:
                        
                        log.write("[{}]\n".format(i+1))            
                        print ("Primo: {}".format( prime))
                        log.write("Primo: {}\n".format( prime))
                        
                        print ("Gerador: {}".format(alpha))
                        log.write("Gerador: {}\n".format(alpha))
                        
                        print ("Elemento do Grupo: {}". format(beta))
                        log.write("Elemento do Grupo: {}\n". format(beta))
                        
                        print ("Logaritmo Discreto: {}".format(discrete_log))
                        log.write("Logaritmo Discreto: {}\n".format(discrete_log))
                        
                        exec_time = time.time()-start_time
                        print ("Tempo de Execução: {:6.3f} seg".format(exec_time))
                        log.write("Tempo de Execução: {:6.3f} seg.\n".format(exec_time))
                        
                        print('''**********************************************************\n''')
                        log.write('''************************\n\n''')
                        time.sleep(1)
                        break
        log.write('''**********************************************************\n''')
        print("Gerado o arquivo {} com o resultado da execução do programa.".format(log.name))                          
    else:
        #sintaxe correta
        print ('''Erro de sintaxe. A sintaxe do programa é:
                  main -d [numero de dígitos do primo] -e [numero de execuções] -t [parametro de seguranca]''')    
else:
    print("Programa principal sendo utilizado como módulo")